.TITLE LOADR .IDENT /15.00/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; PREVIOUSLY MODIFIED BY: ; ; J. W. BERZLE ; D. R. DONCHIN ; M. S. FOX ; J. R. KAUFFMAN ; G. N. LARSEN ; J. M. LAWLER ; T. M. MARTIN ; B. S. MCCARTHY ; L. B. MCCULLEY ; K. L. NOEL ; D. P. RABAHY ; C. A. SILVER ; J. C. FRANZINI ; D. CARROLL ; ; MODIFIED FOR RSX-11M-PLUS VERSION 4.6 BY: ; ; D. CARROLL 9-Jan-1996 15.00 ; DC430 - Include support for 32-bit LBN devices ; ; ; TASK TO LOAD AND CHECKPOINT ALL NONRESIDENT TASKS ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$, CPRDF$, HDRDF$, HWDDF$, PCBDF$, TCBDF$, UCBDF$ .MCALL DIR$, WSIG$S ABODF$ ;DEFINE TASK ABORT CODES CPRDF$ ;DEFINE SYMBOLS & OFFSETS FOR CPR HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS UCBDF$ ;DEFINE UNIT CONTROL BLOCK OFFSETS MAP6= 140000 ; ; LOCAL DATA ; ; READ/WRITE I/O DPB ; LDRDP: .BYTE 3,12. ;DIC, DPB SIZE LDRFC: .BLKW 1 ;FUNCTION CODE .BYTE 1 ;LUN 1 .BLKB 1 ;UNUSED BYTE .BYTE 1 ;EFN 1 .BLKB 1 ;UNUSED BYTE .WORD IOSB ;I/O STATUS DOUBLEWORD ADDRESS .WORD 0 ;NO AST SERVICE ROUTINE LDRBF: .WORD 140000 ;BUFFER ADDRESS (ALWAYS MAP THRU APR6) LDRLN: .BLKW 1 ;BUFFER LENGTH .BLKW 1 ;(UNUSED) LDRBK: .BLKW 2 ;LBN OF I/O TRANSFER IOSB: .BLKW 2 ;I/O STATUS DOUBLEWORD .IF DF U$$DAS ISIZE: .WORD 0 ;SIZE OF USER I SPACE LOAD IREL: .WORD 0 ;RELOCATION BIAS OF I SPACE MUDPT: .WORD 0 ;POINTER TO D WINDOW INTO MU PART ;FOR A MULTI-USER I/D TASK .ENDC .IF DF X$$HDR HDRDB: .WORD 0 ;APR BIAS OF CURRENT HEADER .ENDC ; DF X$$HDR ;+ ; **-$LOADR-LOADER TASK ; ; THE LOADER TASK IS DRIVEN OFF A LIST OF PCB'S QUEUED TO ITS RECEIVE ; QUEUE IN PRIORITY ORDER. THE LOADER'S ACTION FOR EACH PCB IS ; PRIMARILY DRIVEN BY THE TWO PCB STATUS BITS PS.CKP AND PS.OUT. ; SECONDARY INFORMATION WHICH DRIVES THE LOADER IS PASSED IN THE STATUS ; BITS PS.CKR, PS.COM, PS.FXD, AND PS.RON. BASICALLY THE LOADER IS ; CALLED UPON TO PERFORM ONE OF THE FOLLOWING ACTIONS: ; ; 1. (PS.CKP=0,PS.OUT=0) INITIALIZE A TASK FOR EXECUTION WHICH IS ; ALREADY IN MEMORY. (CURRENTLY FOR TRAX-11 USE ONLY.) ; 2. (PS.CKP=0,PS.OUT=1) PERFORM THE INITIAL LOAD OF A NONRESIDENT ; REGION. IF THE REGION IS A TASK REGION (PS.COM=0), INITIALIZE ; ITS HEADER AND ATTACHMENT LIST. IF THE REGION IS A TASK ; REGION WHICH IS NOT SIMPLY BEING FIXED (PS.FXD=0), CALL $BILDS ; TO INITIALIZE THE TASK'S STACK AND PLACE IT IN THE ACTIVE TASK ; LIST. IF THE REGION BEING LOADED ALREADY HAS A PENDING CHECK- ; POINT REQUEST (PS.CKR=1), INITIATE THE CHECKPOINT OF THE REGION ; BY CALLING $ICHKP. ; 3. (PS.CKP=1,PS.OUT=0) WRITE A CHECKPOINT IMAGE OF THE REGION OUT ; TO DISK, FREE ITS MEMORY, AND CONDITIONALLY PLACE THE PCB IN THE ; PARTITION WAIT QUEUE. IF THE REGION IS A TASK REGION (PS.COM=0) ; COPY ITS HEADER FROM THE POOL INTO THE IMAGE FIRST. IF THE ; REGION IS A READ-ONLY COMMON (PS.RON=1), SIMPLY FREE ITS MEMORY ; WITH NO I/O OPERATION. ALL PRIORITY ZERO COMMONS ARE QUEUED ; TO THE LOADR AS PRIORITY 251. COMMONS SO THAT THEY CAN BE ; CHECKPOINTED OUT IMMEDIATELY. THEIR CORRECT PRIORITY IS ; RE-CALCULATED BY THE LOADR. ; 4. (PS.CKP=1,PS.OUT=1) READ THE CHECKPOINT IMAGE OF A REGION BACK ; INTO MEMORY. IF THE REGION BEING LOADED ALREADY HAS A PENDING ; CHECKPOINT REQUEST (PS.CKR=1), INITIATE THE CHECKPOINT OF THE ; REGION BY CALLING $ICHKP. FOR INSTALLED COMMONS WITH PS.NWB ; SET, THE DISK PCB IS DEALLOCATED SO THAT THE COMMON IS NOT ; CHECKPOINTED TO ITS ORIGINAL TASK IMAGE FILE. ;- ; ; GET NEXT REQUEST FROM LOADER QUEUE (SYSTEM STATE) ; ; HERE THE LOADER EXTRACTS THE NEXT PCB FROM ITS RECEIVE QUEUE OR STOPS ; ITSELF IF THERE IS NO REQUEST. IF THE REQUEST IS THE INITIALIZATION ; OF AN ALREADY LOADED TASK OR THE CHECKPOINT OF A READ-ONLY COMMON OR ; THE LOADING OF A REGION CREATED BY THE CREATE REGION DIRECTIVE, THE ; QIO PHASE IS BYPASSED HERE. IF THE REQUEST IS THE CHECKPOINT WRITE OF ; A TASK, ITS HEADER IS COPIED FROM THE POOL TO THE REGION. ; $LOADR:: CALL $SWSTK, 31$ ;SWITCH TO SYSTEM STATE CLR $LDPCB ;INITIALLY CLEAR SAVED PCB WORD MOV $TKTCB,R0 ;PICK UP LOADER TCB ADDRESS ADD #T.RCVL,R0 ;POINT TO RECEIVE LISTHEAD CALL $QRMVF ;REMOVE ENTRY FROM QUEUE BCC 5$ ;IF CC GOT ONE BIT #FE.MXT, $FMASK ;; NO WORK, SO STOP OR EXIT? BNE 4$ ;; IF NE, EXIT CALLR $STPCT ;STOP FOR NOW 4$: MOV $TKTCB, R5 ;; GET LOADER'S TCB CALLR $DREXT ;; EXIT 5$: CLR IOSB ;INDICATE NO I/O ERROR .IF DF U$$DAS CLR ISIZE ;RESET I-SPACE LOADED FLAG .ENDC ;DF, U$$DAS MOV R1,R3 ;CALCULATE ADDRESS OF PCB STATUS WORD ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT - LOADR CALLS DUMMY ROUTINE FOR HOOKPOINT ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- CALL @$SPV02 ;CALL HOOKABLE ENTRY POINT ADD #P.STAT,R3 ; BIT #PS.OUT!PS.CKP,(R3) ;INIT OF ALREADY LOADED TASK? BEQ 7$ ;IF EQ YES BIT #PS.COM,(R3) ;IS IT A COMMON? BEQ 13$ ;IF EQ NO BIT #P2.RON,2(R3) ;IS IT AN INSTALLED READ ONLY COMMON? BEQ 6$ ;IF EQ NO BIT #PS.OUT,(R3) ;CHECKPOINT OF THE READ ONLY COMMON? BNE 13$ ;IF NE NO, MUST BE LOADED BR 12$ ;BYPASS I/O ON CKP OUT OF RO COMMON 6$: TST P.DPCB(R1) ;LOAD OF CREATED REGION? BNE 13$ ;IF NE NO 7$: BIS #PS.OUT,(R3) ;SET ALREADY LOADED TASK OUT OF MEMORY 12$: MOV R1,R4 ;COPY PCB ADDRESS MOV P.TCB(R4),R5 ;SET TCB ADDRESS JMP 82$ ;JOIN AFTER I/O COMPLETION 13$: MOV R1,$LDPCB ;SAVE PCB ADDRESS BIT #PS.OUT!PS.COM,(R3) ;CHECKPOINT WRITE OF TASK? BNE 30$ ;IF NE NO MOV P.HDR(R1),R3 ;GET ADDRESS OF TASK HEADER .IF DF X$$HDR BEQ 30$ ;IF EQ EXTERNAL HEADER, DON'T COPY .ENDC ; DF X$$HDR MOV P.REL(R1),KISAR6 ;SETUP TO ACCESS TASK PARTITION MOV P.TCB(R1),R2 ;POINT TO TCB ADD T.OFF(R2),KISAR6 ;ADD IN OFFSET TO TASK HEADER MOV #140000,R2 ;SET ADDRESS BIAS OF TASK PARTITION MOV H.WND(R3),R4 ;POINT TO NUMBER OF WINDOW BLOCKS TST W.BLVR+2(R4) ;TASK MAPPED TO EXEC? BNE 15$ ;IF NE YES MOV H.DSW(R2),H.DSW(R3) ;COPY DSW TO REAL TASK HEADER 15$: MOV H.HDLN(R3),R4 ;GET LENGTH OF HEADER IN BYTES ASR R4 ;CONVERT TO WORD COUNT 20$: MOV (R3)+,(R2)+ ;MOVE HEADER INTO TASK PARTITION DEC R4 ;ANY MORE WORDS TO MOVE? BGT 20$ ;IF GT YES 30$: RETURN ;RETURN TO TASK STATE ; ; PERFORM ACTUAL I/O TRANSFER (TASK STATE) ; ; HERE THE LOADER SETS UP THE QIOW DPB AND PERFORMS THE ONE OR MORE I/O ; TRANSFERS REQUIRED. AFTER SETTING UP THE I/O FUNCTION CODE AND BYTE ; COUNT THE LOADER MUST CALCULATE THE DISK ADDRESS AND UCB ADDRESS. IF ; THERE IS A DISK PCB, THE LOADER CODE ASSUMES IT IS A CHECKPOINT PCB, ; AND THE DATA STRUCTURES ARE SUCH THAT THIS WORKS FOR COMMON TASK IMAGE ; FILE PCB'S AS WELL. OTHERWISE THE REQUEST MUST BE FOR A TASK TO OR ; FROM ITS TASK IMAGE FILE. FOR AN INITIAL TASK LOAD THIS MEANS THE ; ADDRESS IN T.LBN. FOR A CHECKPOINT OPERATION THIS MEANS THE ; ADDRESS AT T.LBN MINUS THE PARTITION SIZE (THE PREALLOCATED CHECKPOINT ; SPACE). ; ; THE I/O TRANSFER IS SPECIFIED TO THE EXECUTIVE BY SPECIFYING A BUFFER ; ADDRESS OF 140000 AND LOADING UISAR6 WITH THE PHYSICAL MEMORY OFFSET ; OF THE FIRST 32W BLOCK OF THE TRANSFER. THIS ALLOWS THE EXECUTIVE TO ; FIND THE CORRECT START ADDRESS VIA $RELOC. THE SIZE OF THE TRANSFER ; CAN BE ANYTHING SINCE THE EXECUTIVE DOES NOT ADDRESS CHECK PRIVILEGED ; TASKS. THE PROCESSOR PRIORITY IS RAISED TO PR7 TO INHIBIT CONTEXT ; SWITCHING BETWEEN THE LOADING OF UISAR6 AND THE EXECUTION OF THE QIOW ; DIRECTIVE. THE PRIORITY ONLY REMAINS AT PR7 FOR SHORT INSTRUCTION ; SEQUENCES AT TASK STATE IN THE LOADER, NATURALLY DROPPING TO PR0 AND ; ALLOWING CONTEXT SWITCHING WHEN THE QIOW IS EXECUTED. ON RETURN TO ; LOADER FROM THE QIOW, HOWEVER, THE PRIORITY IS RETURNED TO PR7 ; AUTOMATICALLY AND UISAR6 WILL BE RELOADED IF ANOTHER TRANSFER IS ; REQUIRED. ; 31$: MOV $LDPCB, R4 ;RETRIEVE SAVED PCB ADDRESS BEQ $LOADR ;IF EQ THERE WAS NONE, TRY AGAIN MOV P.TCB(R4),R5 ;GET TCB ADDRESS (IF TASK PARTITION) MOV R4,R3 ;CALCULATE ADDRESS OF PCB STATUS WORD ADD #P.STAT,R3 ; .IF DF C$$LDR BIT #F5.LDR, $FMSK5 ; REMOTE LOADER SUPPORT? BEQ 49$ ; IF EQ NO MOV P.DPCB(R4), R1 ; POINT TO DISK PCB BEQ 40$ ; IF EQ THERE ISN'T ONE MOV P.MAIN(R1),R1 ; GET MAIN PCB MOV P.UCB(R1), R1 ; SAVE UCB ADDRESS BR 41$ 40$: MOV T.LDV(R5), R1 ; SAVE LOAD DEVICE UCB ADDRESS 41$: MOV U.RED(R1), R1 ; FOLLOW REDIRECT CHAIN CMP R1, U.RED(R1) ; FOUND REAL DEVICE? BNE 41$ ; IF NE, NOPE - KEEP GOING ASSUME U.DCB CMP (R1), $XXLOW ; INSTALLED ON A REMOTE DEVICE? BLO 49$ ; IF LO, NOPE - LOCAL DEVICE CMP (R1), $XXHGH BHI 49$ ; IF HI, NOPE - LOCAL DEVICE 42$: CALL $SWSTK, 48$ ; SWITCH TO SYSTEM STATE MOV #< P$BLK+ 77>/ 100, R1 ;; ROUNDED SIZE OF PACKET CLR R0 ;; INDICATES IMMEDIATE RETURN DESIRED CALL $CPALO ;; GET BUFFER FROM CPRBUF BCC 43$ ;; RESOURCES AVAILABLE BIS #1, $UMPS ;; PROPAGATE STATUS TO USER-MODE RETURN 43$: MOV R0, KISAR6 ;; MAP NEWLY ALLOCATED PACKET MOV #MAP6, R0 ;; BASE ADDRESS OF PACKET ; ; LOAD HEADER & PARAMETER AREAS ; CLRB H$ICNT(R0) ;; NO ITEMS MOV P.REL(R4),P$ADDR(R0) ;; BIAS IN MEMORY CLR P$ADDR+2(R0) ;; OFFSET IS ALWAYS ZERO BIT #PS.OUT, P.STAT(R4) ;; IS THE REGION IN OR OUT OF MEMORY? BNE 44$ ;; IF NE, IT'S OUT MOVB #HT$CKW, H$TYPE(R0) ;; MUST BE WRITE REQUEST BR 45$ 44$: XXX= PS.CKP!PS.COM BIT #XXX, P.STAT(R4) ;; IS THIS CHECKPOINT OR COMMON? BEQ 46$ ;; IF EQ, NO - MUST BE A TASK LOAD MOVB #HT$CKR, H$TYPE(R0) ;; CHECKPOINT READ REQUEST 45$: MOV P.DPCB(R4), R1 ;; GET DISK PARTITION CONTROL BLOCK MOV P.LBN+2(R1),P$BLK(R0) ;; RELATIVE BLOCK NUMBER CMP P.MAIN(R1),R1 ;; IS THIS A CKP PCB? BEQ 455$ ;; IF EQ NO MOV P.REL(R1),P$BLK(R0) ;; RELATIVE BLOCK NUMBER MOV P.MAIN(R1),R1 ;; GET CKP FILE PCB ADDRESS 455$: MOV P.IID(R1), P$IID(R0) ;; USE COMMON IMAGE INDEX MOV P.SIZE(R4), P$LEN(R0) ;; # OF 32. WORD BLOCKS TO TRANSFER BR 47$ 46$: MOVB #HT$ILD, H$TYPE(R0) ;; IMAGE LOAD REQUEST MOV T.IID(R5), P$IID(R0) ;; USE TASK IMAGE INDEX ADD T.OFF(R5), P$ADDR(R0) ;; ADJUST DESTINATION BIAS 47$: CPSEN$ #SN$TSK,KISAR6,#P$BLK+2 ;; SEND PACKET TO CPRSYS VIA KXDRV MOV R0, KISAR6 ;; MAP PACKET MOV MAP6+H$STAT, IOSB ;; PROPAGATE STATUS CALLR $CPDEA ;; RELEASE THE CPRBUF SPACE 48$: BCS 42$ ; RESOURCE WAS LACKING, TRY AGAIN JMP 81$ ; CONTINUE WITH POST-PROCESSING 49$: .ENDC ; DF C$$LDR MOV #IO.RLB,LDRFC ;ASSUME READ FUNCTION BIT #PS.OUT,(R3) ;CHECKPOINT WRITE REQUEST? BNE 50$ ;IF NE NO MOV #IO.WLB,LDRFC ;SET WRITE FUNCTION 50$: BIT #PS.COM,(R3) ;COMMON ? BEQ 501$ ;IF EQ, NO BIT #P2.LDD,P.ST2(R4) ;WAS LOAD DEVICE DISABLED/DISMOUNTED ? BNE 51$ ;IF NE, YES BR 52$ ;ELSE CONTINUE PROCESSING 501$: BIT #T4.LDD,T.ST4(R5) ;TASK LOAD DEVICE DISABLED ? BEQ 52$ ;IF EQ NO, ALL IS OK BIT #PS.CKP,(R3) ;CHECKPOINT REQUEST ? BEQ 51$ ;IF EQ NO, FAILURE BIT #T3.CAL,T.ST3(R5) ;CHECK POINT SPACE IN TASK ? BEQ 52$ ;IF EQ NO, IT'S OK 51$: MOVB #IE.PRI,IOSB ;FORCE I/O FAILURE 52$: CLR R0 ;HIGH PORTION OF SIZE MOV P.SIZE(R4),R1 ;ASSUME SIZE OF TRANSFER BIT #PS.CKP!PS.COM,(R3) ;CHECKPOINT REQUEST OR COMMON? BNE 55$ ;IF NE YES ; ; THIS IS AN INITIAL TASK LOAD. SET SIZE FROM T.TKSZ, TASK LOAD SIZE ; AND CLEAR FLAG INDICATING D SPACE TASK. ; MOV T.TKSZ(R5),R1 ;USE TASK TRANSFER SIZE INSTEAD 55$: ASHC #6,R0 ;CONVERT TO BYTE COUNT MOV R0,R2 ;HIGH PORTION OF SIZE MOV R1,-(SP) ;OUT OF REGISTERS - USE STACK FOR LOW PORTION MOV #LDRBK,R0 ;POINT TO LBN MOV P.DPCB(R4),R1 ;POINT TO DISK PCB BEQ 56$ ;IF EQ THERE IS NONE MOV P.REL(R1),2(R0) ;GET RELATIVE POSITION IN FILE MOV P.MAIN(R1),R1 ;POINT TO MAIN PCB MOV P.LBN(R1),(R0)+ ;SET HIGH BITS OF BLOCK ADDRESS ADD P.LBN+2(R1),(R0) ;ADD LOW BITS TO RELATIVE POSITION ADC -(R0) ;PROPAGATE CARRY MOV P.UCB(R1),-(SP) ;SAVE UCB ADDRESS BR 60$ ; 56$: MOVB T.LBN(R5),(R0)+ ;SET HIGH BITS OF BLOCK ADDRESS CLRB (R0)+ ; ;DC430 .IF DF,E$$LBN ; EXTENDED LOGICAL BLOCKS ;DC430 ;DC430 TSTB $FMSK6 ; SYSTEM SUPPORT 32-BIT LBN DEVICES ;DC430 BPL 57$ ; IF PL, NOPE, LEAVE AS ZERO ;DC430 MOVB T.LBNX(R5),-1(R0) ; LOAD IN THE HIGH ORDER LBN INFO ;DC430 57$: ; REFERENCE LABEL ;DC430 ;DC430 .ENDC ;DF,E$$LBN ;DC430 ;DC430 MOV T.LBN+1(R5),(R0) ;SET LOW BITS OF BLOCK ADDRESS MOV T.LDV(R5),-(SP) ;SAVE LOAD DEVICE UCB ADDRESS BIT #PS.CKP,(R3) ;IS THIS A CHECKPOINT OPERATION? .IF NDF U$$DAS BEQ 60$ ;IF EQ NO .IFF ; NDF U$$DAS BNE 58$ ;IF NE YES ; ; THIS IS AN INITIAL LOAD. IF THE TASK HAS USER INSTRUCTION AND DATA ; SPACE ENABLED, ADJUST SO THAT THE FIRST LOAD GETS THE DATA SPACE IN. ; THEN WE WILL LOCATE I SPACE THROUGH THE TASK HEADER. ; BIT #T4.DSP,T.ST4(R5) ;TASK BUILT WITH SEPARATE I/D SPACES ? BEQ 60$ ;IF EQ NO DEC ISIZE ;AND INDICATE PARTIAL D SPACE LOAD BR 60$ ;REJOIN COMMON CODE .ENDC ; DF U$$DAS 58$: MOV P.SIZE(R4),R1 ;PICK UP MAXIMUM SIZE OF TASK ADD #7,R1 ;ROUND UP TO NEXT 512. BLOCK ROR R1 ;CONVERT TO 512. WORD BLOCKS ASR R1 ; ASR R1 ; .IF DF U$$DAS SUB T.ISIZ(R5),(R0) ;ADJUST BY SIZE OF I SPACE SBC -2(R0) ; .ENDC ; DF U$$DAS SUB R1,(R0) ;CALCULATE STARTING LBN OF CKP AREA SBC -(R0) ; 60$: ; ; SINCE WE'RE IN USER-MODE AT THIS POINT WE HAVE TO USE UISAR6 TO MAP OUR ; HEADER AND SO WE MUST DISABLE INTERRUPTS LEST WE HAVE OUR CONTEXT RELOADED ; MOV $SAHPT, R1 ; GET ADDRESS OF LOADER'S HEADER MOVB #PR7, PS ;;; LOCK OUT INTERRUPTS MOV $SAHDB, UISAR6 ;;; MAP LOADER'S HEADER PLF = / 100 * 400 MOV #PLF + 6, UISDR6 ;;; ALLOW WRITE ACCESS MOV (SP)+, H.LUN(R1) ;;; ASSIGN LUN 1 TO LOAD DEVICE CLRB PS ;;; ALLOW INTERRUPTS MOV P.REL(R4), R1 ; PICK UP RELOCATION BIAS OF PARTITION BIT #PS.CKP!PS.COM, (R3) ; CHECKPOINT REQUEST OR COMMON? BNE 65$ ; IF NE YES ADD T.OFF(R5), R1 ; ELSE ADD IN OFFSET TO TASK IMAGE 65$: MOV #177000, LDRLN ; SET TENTATIVE LENGTH OF TRANSFER ; ; AT THIS POINT WE HAVE: ; ; R2,(SP) = TOTAL SIZE OF TRANSFER TO PERFORM ; R1 = RELOCATION BIAS OF LOAD AREA IN PHYSICAL MEMORY ; R4 = PCB ADDRESS OF TRANSFER PCB ; R5 = TCB ADDRESS OF TASK (IF TASK REGION) ; LDRBK = HIGH ORDER PART OF DISK BLOCK ADDRESS TO TRANSFER ; LDRBK+2 = LOW ORDER PART OF DISK BLOCK ADDRESS ; SUB #177000, (SP) ; REDUCE ACTUAL COUNT TO TRANSFER SBC R2 BGE 70$ ; IF GE FULL TRANSFER ADD (SP), LDRLN ; ELSE REDUCE SIZE OF TRANSFER BEQ 80$ ; IF EQ LAST TRANSFER DID IT 70$: TSTB IOSB ; FORCED I/O ERROR (DUE TO DISMOUNT)? BMI 80$ ; IF MI YES, MAKE IT LOOK LIKE DONE MOVB #PR7, PS ;;; LOCK OUT INTERRUPTS MOV R1, UISAR6 ;;; SET APR BIAS FOR TRANSFER 71$: DIR$ #LDRDP ;;; REQUEST I/O TRANSFER BCC 75$ ;;; IF CC LOAD SUCCEEDED WSIG$S ;;; WAIT FOR SIGNIFICANT EVENT BR 71$ ;;; RETRY I/O 75$: CLRB PS ;;; ALLOW INTERRUPTS ADD #1770, R1 ; UPDATE APR BIAS ADD #177, LDRBK+2 ; UPDATE BLOCK NUMBER ADC LDRBK TST R2 ; WAS IT THE LAST TRANSFER? BLT 80$ ; IF LT YES TSTB IOSB ; WAS TRANSFER SUCCESSFUL? BPL 65$ ; IF PL YES - GO FOR NEXT ONE 80$: TST (SP)+ ; POP LOW-ORDER TRANSFER COUNT ; ; IF THIS IS AN I/D SPACE TASK, RESET PARAMETERS AND READ IN I SPACE ; SECTION WITH PARAMETERS FROM WINDOW ZERO IN THE TASK HEADER. ; .IF DF U$$DAS TST ISIZE ;TASK USE I/D SPACE (AND NOT ALREADY ;LOADED BOTH SPACES) ? BPL 807$ ;IF PL EITHER NOT D SPACE OR ALREADY ;ALL LOADED CALL $SWSTK,805$ ;SWITCH TO SYSTEM STATE MOV #ISIZE,R0 ;POINT TO IMPURE AREA MOV P.REL(R4),KISAR6 ;POINT TO TASK REGION ADD T.OFF(R5),KISAR6 ;ADJUST TO HEADER AREA CMPB #17,140000+H.IPS ;SUCCESSFUL READ ? BNE 803$ ;IF NE NO MOV H.NLUN+140000,R1 ;GET NUMBER OF LUNS ASL R1 ;CONVERT ASL R1 ;TO INDEX ADD #140000+H.NLUN+4,R1 ;POINT TO TASK I SPACE WINDOW MOV W.BSIZ(R1),(R0)+ ;SAVE SIZE OF I SPACE WINDOW ; IF A TASK HAS BEEN INSTALLED TWICE WITH DIFFERENT /XHR SETTINGS, W.BOFF ; IN WINDOWS 0 AND 1 MAY NOT BE CORRECT FOR THIS INSTANCE OF THE TASK. ; HERE, WE SET W.BOFF IN WINDOW 0 CORRECTLY SINCE WE USE IT BELOW TO FIGURE ; OUT WHERE TO LOAD THE I-SPACE. WINDOW 1 IS SETUP BY $MAPTK. SUB W.BOFF+W.BLGH(R1),W.BOFF(R1) ;;CALC SIZE OF I-SPACE ADD T.OFF(R5),W.BOFF(R1) ;;SET CORRECT OFFSET FOR WINDOW 0 MOV W.BOFF(R1),(R0) ;;SAVE OFFSET INTO PARTITION 803$: RETURN ;BACK TO USER STATE 805$: TST ISIZE ;SHOULD WE TRY I SPACE READ ? BLE 807$ ;IF LE, NO MOV ISIZE,R1 ;GET SIZE OF USER I WINDOW ASH #6,R1 ;CONVERT TO SIZE IN BYTES MOV R1,-(SP) ;SET UP FOR REGION LOAD CODE MOV IREL,R1 ;GET OFFSET TO I SPACE ADD P.REL(R4),R1 ;SET UP RELOCATION BIAS MOV #LDRBK,R0 ;GET ADDRESS OF BLOCK NUMBER MOVB T.LBN(R5),(R0)+ ;SET HIGH PART OF BLOCK NUMBER CLRB (R0)+ ;CLEAR HIGH BITS ;DC430 .IF DF,E$$LBN ; EXTENDED LOGICAL BLOCKS ;DC430 ;DC430 TSTB $FMSK6 ; SYSTEM SUPPORT 32-BIT LBNS ;DC430 BPL 806$ ; IF PL, NOPE, CONTINUE ;DC430 MOVB T.LBNX(R5),-1(R0) ; LOAD HIGH ORDER LBN BYTE ;DC430 806$: ; REFERENCE LABEL ;DC430 ;DC430 .ENDC ;DF,E$$LBN ;DC430 ;DC430 MOV T.LBN+1(R5),(R0) ;SET LOW PART OF BLOCK NUMBER SUB T.ISIZ(R5),(R0) ;ADJUST BACKWARDS TO START OF SBC -(R0) ;I SPACE CLR ISIZE ;INDICATE FINAL PHASE OF LOAD JMP 65$ ;GO LOAD USER DATA SPACE SECTION 807$: ;REFERENCE LABEL .ENDC ; DF U$$DAS ; ; POST PROCESSING FOR CHECKPOINT WRITE (SYSTEM STATE) ; ; HERE THE LOADER CHECKS THE I/O STATUS, DEALLOCATES THE TASK HEADER IF ; THE REGION WAS A TASK REGION, AND DETERMINES IF THE REGION PCB SHOULD ; BE ENTERED INTO THE PARTITION WAIT QUEUE. TASK REGIONS ALWAYS GO INTO ; THE PARTITION WAIT QUEUE AND COMMONS GO IN IF P.PRI IS NONZERO (THERE ; IS A RESIDENT MAPPED TASK). FINALLY THE REGIONS MEMORY IS RELEASED ; ALLOWING $NXTSK TO ATTEMPT TO BRING IN THE HIGHEST PRIORITY WAITING ; REGION. ; 81$: CALL $SWSTK,$LOADR ;SWITCH TO SYSTEM STATE 82$: ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT - LOADR CALLS DUMMY ROUTINE FOR HOOKPOINT ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- CALL @$SPV03 ;CALL HOOKABLE ENTRY POINT BIT #PS.OUT,(R3) ;REGION IN MEMORY? BNE 870$ ;IF NE NO BIT #PS.COM,(R3) ;IS THIS A COMMON? BEQ 825$ ;IF EQ NO BIT #P2.CPC,P.ST2(R4) ;IS THIS A CPCR CKP WRITE? BEQ 825$ ;IF EQ NO TSTB IOSB ;SUCCESSFUL WRITE? BMI 90$ ;IF MI NO BR 91$ ;OTHERWISE AVOID REAL CHECKPOINT WRITE ;PARTITION DEALLOCATION 825$: BIT #PS.DEL,(R3) ;IS REGION MARKED FOR DELETE? BEQ 83$ ;IF EQ NO TST P.ATT(R4) ;IS THERE ANYONE LEFT ATTACHED? BNE 83$ ;IF NE YES MOV R4,R1 ;COPY PCB POINTER CALL $RLPR1 ;RELEASE ITS MEMORY MOV R4,R0 ;COPY PCB POINTER CALLR $RLCPS ;RELEASE CHECKPOINT SPACE & DEA PCB'S 83$: TSTB IOSB ;SUCCESSFUL WRITE? BMI 90$ ;IF MI NO .IF DF E$$XPR BIT #PS.AST,P.STAT(R4) ;REGION HAVE AST PENDING ? BNE 84$ ;IF NE YES, P.SWSZ IS AST LISTHEAD ;NOT SWAP SIZE. MOV P.SWSZ(R4),P.SIZE(R4) ;SET SIZE FROM SWAP SIZE 84$: ;REFERENCE LABEL .ENDC BIS #PS.OUT,(R3) ;SET REGION OUT OF MEMORY CLR $LDPCB ;CLEAR LOADER PCB POINTER BIT #PS.COM,(R3) ;IS IT A COMMON REGION? BEQ 844$ ;IF EQ, NO - MUST BE A TASK REGION CLRB P.PRI(R4) ;RE-INITIALIZE PRIORITY OF COMMON TSTB P.RMCT(R4) ;ANYONE MAPPED TO COMMON ? BEQ 85$ ;IF EQ, NO - LEAVE PRIORITY AT ZERO MOV R4,R1 ;COPY PCB POINTER ADD #P.ATT,R1 ;POINT TO ATTACHMENT LIST ASSUME A.PCBL 841$: MOV (R1),R1 ;GET FIRST/NEXT ADB BEQ 843$ ;IF EQ, END OF LIST TSTB A.MPCT(R1) ;TASK MAPPED THRU THIS DESCRIPTOR ? BEQ 841$ ;IF EQ, NO - DON'T LOOK AT PRIORITY MOV A.TCB(R1),R0 ;GET MAPPED TASK'S TCB CMPB P.PRI(R4),T.PRI(R0) ;REGION PRIORITY ALREADY GREATER ;THAN SOMEONE ELSES TASK ? BHIS 841$ ;IF SO, DON'T UPDATE PRIORITY MOVB T.PRI(R0),P.PRI(R4) ;UPDATE REGION'S PRIORITY BR 841$ ;AND EXAMINE NEXT ATTACHMENT 843$: INCB P.PRI(R4) ;COMMON REGION'S PRIORITY IS ALWAYS BR 85$ ;ONE GREATER THAN HIGHEST PRIORITY TASK 844$: ;REFERENCE LABEL .IF DF A$$CNT MOV P.TCB(R4),R0 ;GET TCB ADDRESS MOV KISAR6,-(SP) ;SAVE MAPPING MOV T.ACN(R0),KISAR6 ;MAP ACCOUNTING BLOCK BEQ 845$ ;IF EQ, NO ACCOUNTING CMPB #BT.TAB,@#B.TYP+140000 ;IS THIS A TAB BNE 845$ ;IF NE NO ADD #1,@#B.TCKP+2+140000 ;COUNT TASK CHECKPOINT ADC @#B.TCKP+140000 ; 845$: MOV (SP)+,KISAR6 ;RESTORE MAPPING .ENDC ;A$$CNT MOV P.HDR(R4),R0 ;GET ADDRESS OF TASK HEADER .IF DF X$$HDR BEQ 85$ ;IF EQ EXTERNAL HEADER, DON'T DEALLOCATE .ENDC ; DF X$$HDR MOV H.HDLN(R0),R1 ;GET LENGTH OF HEADER IN BYTES CALL $DEACB ;DEALLOCATE HEADER 85$: MOV R4,R1 ;SET PCB ADDRESS TSTB P.PRI(R1) ;DOES IT HAVE A PRIORITY? BEQ 87$ ;IF EQ NO, DO NOT PUT IN WAIT QUEUE MOV P.MAIN(R1),R0 ;CALCULATE ADDR OF WAIT QUEUE LISTHEAD ADD #P.WAIT,R0 ; CALL $QINSP ;INSERT TASK BACK IN PARTITION WAIT QUEUE 87$: CALLR $RLPR1 ;RELEASE PARTITION 870$: BR 110$ ;EXTEND BRANCH ; ; CHECKPOINT WRITE FAILURE (SYSTEM STATE) ; ; ON CHECKPOINT WRITE FAILURES A DIAGNOSTIC MESSAGE BLOCK IS QUEUED TO ; TKTN AND THE STATUS OF THE REGION AND ANY MAPPED TASKS IS RESET, ; ALLOWING THE TASKS TO RUN AS IF THE CHECKPOINT WRITE REQUEST HAD NOT ; OCCURED. ANY CHECKPOINT SPACE ALLOCATED FOR THE REGION IS RELEASED. ; 90$: MOV #T.NCWF,R0 ;SET CHECKPOINT WRITE FAILURE MOV R4,R5 ;COPY PCB ADDRESS MOV $SAHPT,R4 ;PICK UP PTR TO OWN HEADER MOV KISAR6,-(SP) ;SAVE MAPPING MOV $SAHDB,KISAR6 ;MAP OWN HEADER MOV H.LUN(R4),R4 ;PICK UP UCB ADDRESS OF WRITE ERROR MOV (SP)+,KISAR6 ;RESTORE MAPPING CALL $DVMSG ;OUTPUT MESSAGE MOV R5,R4 ;RESET PCB ADDRESS IN R4 ; ; UNBLOCK MAPPED TASKS & FREE CHECKPOINT SPACE (SYSTEM STATE SUBROUTINE) ; ; THIS ROUTINE IS CALLED AFTER A REGION LOAD OPERATION OR AN UNSUCCESS- ; FULL CHECKPOINT WRITE OPERATION TO UNBLOCK ALL MAPPED TASKS AND FREE ; ANY SPACE WHICH MAY BE ALLOCATED IN A CHECKPOINT FILE. IF THE REGION ; HAS HAD A LOAD FAILURE, THEN ALL MAPPED TASKS ARE ABORTED. ; ; INPUTS: ; ; R4=PCB ADDRESS. ; ; OUTPUTS: ; ; R4 AND R5 PRESERVED. ; 91$: MOV P.ATT(R4),R2 ;POINT TO FIRST ATTACHMENT DESCRIPTOR BEQ 94$ ;IF EQ THERE IS NONE 92$: MOVB A.MPCT(R2),R1 ;PICK UP MAPPING COUNT THRU DESCRIPTOR BEQ 93$ ;IF EQ TASK NOT MAPPED BIT #PS.LFR,P.STAT(R4) ;LOAD FAILURE THIS REGION? BEQ 925$ ;IF EQ NO MOV R2,-(SP) ;SAVE ATTACHMENT DESCRIPTOR ADDRESS MOV A.TCB(R2),R0 ;POINT TO ATTACHED TCB DEC T.STAT(R0) ;REDUCE BLOCKING COUNT BPL 923$ ;IF PL TASK ALREADY ACTIVE BIC #TS.EXE,T.STAT(R0) ;ELSE SET TASK ACTIVE MOV T.PCB(R0),R1 ;POINT TO TASK PCB BIC #PS.FXD,P.STAT(R1) ;CLEAR FIXED BIT CALL $BILDS ;BUILD STACK AND PLACE IN ATL MOV (SP),R2 ;RESTORE ATTACHMENT DESCRIPTOR ADDRESS 923$: CLRB A.MPCT(R2) ;ZERO MAPPING COUNT MOV A.TCB(R2),R1 ;POINT TO MAPPED TCB BIT #T2.ABO,T.ST2(R1) ;TASK ALREADY MARKED FOR ABORT? BNE 9241$ ;IF NE YES MOV #S.CLRF,R0 ;SET CODE FOR LOAD FAILURE BIT #PS.CKP,P.STAT(R4) ;CHECKPOINT READ? BEQ 924$ ;IF EQ NO MOV #S.CCRF,R0 ;SET CODE FOR CHECKPOINT READ FAILURE 924$: CALL $ABTSK ;ABORT TASK 9241$: MOV (SP)+,R2 ;RESTORE R2 BR 93$ ; 925$: MOV A.TCB(R2),R0 ;POINT TO MAPPED TASK'S TCB DEC T.STAT(R0) ;REDUCE BLOCKING COUNT BNE 93$ ;IF NE TASK IS STILL BLOCKED CALL $SETCR ;SCHEDULE TASK 93$: MOV (R2),R2 ;POINT TO NEXT ATTACHMENT DESCRIPTOR BNE 92$ ;IF NE THERE IS ONE 94$: MOV R4,R2 ;COPY PCB POINTER ADD #P.STAT,R2 ;POINT AT PARTITION STATUS WORD BIT #PS.COM,(R2)+ ;IS THIS A COMMON? BEQ 95$ ;IF EQ NO BIT #P2.CPC,(R2) ;IS THIS A CPCR CKP WRITE? BEQ 945$ ;IF EQ NO BIC #P2.CPC,(R2) ;INDICATE CPCR COMPLETED ASSUME P.ST2, BIC #PS.CKP,-(R2) ;CHECKPOINT COMPLETED MOV R4,R0 ;COPY PCB ADDRESS CALLR $NXTSK ;REALLOCATE PARTITION IF NECESSARY 945$: BIT #PS.LFR,-(R2) ;LOAD FAILURE THIS REGION? BNE 96$ ;IF NE YES 95$: MOV R4,R0 ;COPY PCB POINTER CALLR $RLCPS ;RELEASE CHECKPOINT SPACE 96$: RETURN ; ; ; POST PROCESSING FOR REGION LOAD (SYSTEM STATE) ; COPY HEADER & CHECK I/O STATUS ; ; HERE THE LOADER SETS UP A COPY OF THE TASK HEADER IN THE POOL AND ; DETERMINES IF A LOAD FAILURE HAS OCCURRED. ; 110$: BIC #PS.OUT!PS.LFR,(R3) ;CLEAR OUT AND LOAD FAILURE BIT #PS.COM,(R3) ;IS REGION A COMMON? BEQ 112$ ;IF EQ NO JMP 143$ ;YES, SKIP HEADER PROCESSING 112$: ;REFERENCE LABEL MOV P.REL(R4),KISAR6 ;MAP TO TASK PARTITION .IF DF X$$HDR TSTB T.HDLN(R5) ;TASK HAVE EXTERNAL HEADER BEQ 113$ ;IF EQ, NO. CALCULATE OFFSET TO HEADER BIT #PS.CKP,(R3) ;CHECKPOINT READ ? BNE 114$ ;IF NE, YES - EXAMINE EXTRNAL HEADER 113$: .ENDC ; DF X$$HDR ADD T.OFF(R5),KISAR6 ;ADD IN OFFSET TO TASK HEADER 114$: MOV 140000+H.HDLN,R1 ;ASSUME SUCCESSFUL READ CMPB #17,140000+H.IPS ;VALID TASK IMAGE? BNE 115$ ;IF NE NO TREAT AS UNSUCCESSFUL READ TSTB IOSB ;SUCCESSFUL READ? BPL 120$ ;IF PL YES 115$: MOVB #-1,IOSB ;INDICATE LOAD FAILURE MOV #H.NLUN+2+W.BLGH+2,R1 ;SETE LENGTH OF MINIMUM HEADER CLR 140000+H.NLUN ;CLEAR NUMBER OF LUNS WORD 120$: MOV R1,2(SP) ;SAVE LENGTH OF HEADER .IF DF X$$HDR TSTB T.HDLN(R5) ;TASK HAVE EXTERNAL HEADER ? BEQ 125$ ;IF EQ NO, GO TRY TO ALLOCATE MOV #140000,R0 ;SET VIRTUAL ADDRESS OF XTRNL HEADER BIT #PS.CKP,(R3) ;CHECKPOINT READ OPERATION ? BNE 122$ ;IF NE YES, NO HEADER MANIPULATION REQUIRED CLR P.HDR(R4) ;INDICATE EXTERNAL HEADER FOR PCB MOV P.REL(R4),HDRDB ;SET BLOCK NUMBER OF EXTERNAL HEADER BR 131$ ;RE-ENTER CODE FLOW 122$: JMP 1401$ ;STRETCH BRANCH FROM ABOVE .ENDC ; DF X$$HDR 125$: CALL $ALOCB ;ALLOCATE A BLOCK FOR TASK HEADER BCC 130$ ;IF CC BLOCK ALLOCATED BIS #PS.OUT,(R3) ;MARK REGION AS OUT OF MEMORY ; ; NO NEED TO CHANGE FOLLOWING REFERENCE TO $HEADR TO SUPPORT EXTERNAL HEADER ; MOV @$HEADR,R0 ;GET SAVED STACK POINTER MOV #81$,4(R0) ;ALTER RETURN ADDRESS CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 130$: MOV R0,P.HDR(R4) ;SAVE ADDRESS OF NEW HEADER 131$: MOV #140000,R2 ;SET APR6 ADDRESS BIAS MOV R0,R1 ;CALC RELATIVE HEADER GUARD WORD POINTER TST -(R1) ; MOV R1,H.GARD(R2) ; MOV R1,H.WND(R2) ;CALCULATE NUMBER OF WINDOW BLOCKS PTR MOV H.NLUN(R2),R1 ;CALCULATE NUMBER OF LUN WORDS ASL R1 ; ASL R1 ; ADD #H.NLUN+4,R1 ;FINISH CALCULATION ADD R1,H.WND(R2) ; MOV 2(SP),R1 ;RETRIEVE LENGTH OF HEADER IN BYTES MOV R1,H.HDLN(R2) ;SET LENGTH OF HEADER ADD R1,H.GARD(R2) ;FINISH GUARD WORD CALCULATION .IF DF X$$HDR .IF DF F$$MAP CLR H.FMAP(R2) ;ASSUME TASK DOES NOT HAVE FAST MAP ENABLED .ENDC ; DF F$$MAP .IF DF C$$DFB & C$$RTB CLR H.LUTE(R2) ;ASSUME TASK DOES NOT HAVE RUN TIME BINDING .ENDC ; DF C$$DFB & C$$RTB TST P.HDR(R4) ;TASK HAVE EXTERNAL HEADER ? BNE 139$ ;IF NE NO, GO COPY MOV R4,-(SP) ;SAVE PCB ADDRESS MOVB T.HDLN(R5),R0 ;GET SIZE OF TOTAL HEADER .IF DF F$$MAP BIT #T4.FMP,T.ST4(R5) ;TASK HAVE FAST MAP ENABLED? BEQ 133$ ;IF EQ NO SUB #H$$FMX,R0 ;SUBTRACT OUT SIZE OF FAST MAP EXTENSION 133$: .ENDC ; DF F$$MAP .IF DF C$$DFB & C$$RTB BIT #T4.DFB,T.ST4(R5) ;TASK HAVE DEFERRED BINDING? BEQ 135$ ;IF EQ NO BIT #F5.RTB,$FMSK5 ;TASK HAVE RUN TIME BINDING? BEQ 135$ ;IF EQ NO MOV H.NLUN(R2),R1 ;CALCULATE SIZE OF LUT EXTENSION ASL R1 ; ASL R1 ; ADD #77,R1 ;ROUND TO NEAREST 32. WORD BLOCK ASH #-6,R1 ; MOV R1,H.LUTE(R2) ;SAVE SIZE SUB R1,R0 ;SUBTRACT OUT SIZE OF LUT EXTENSION 135$: .ENDC ; DF C$$DFB & C$$RTB ASH #6,R0 ;CONVERT TO BYTES MOV P.REL(R4),R1 ;SET APR DISPLACEMENT OF DESTINATION MOV R1,R3 ;COPY TO SOURCE DISPLACEMENT ADD T.OFF(R5),R1 ;CALCULATE SOURCE BIAS MOV #120000,R2 ;SET SOURCE DISPLACEMENT MOV #140000,R4 ;SET DESTINATION DISPLACEMENT CALL $BLXIO ;COPY HEADER MOV (SP)+,R4 ;RESTORE PCB ADDRESS MOV R4,R3 ;RESTORE POINTER ADD #P.STAT,R3 ;TO PARTITION STATUS WORD MOV HDRDB,KISAR6 ;MAP TO EXTERNAL HEADER MOV #140000,R0 ;SET VIRTUAL ADDRESS OF HEADER .IF DF F$$MAP BIT #T4.FMP,T.ST4(R5) ;TASK HAVE FAST MAP ENABLED? BEQ 1371$ ;IF EQ NO MOVB T.HDLN(R5),R1 ;GET LENGTH OF HEADER IN BYTES ASH #6,R1 ;CONVERT TO BYTE OFFSET ADD #140000-<64.*H$$FMX>,R1 ;POINT TO FAST MAP AREA MOV R1,H.FMAP(R0) ;SET ADDRESS OF FAST MAP AREA MOV #<<+15.>/16.>,R2 ;GET NUMBER OF ;PASSES THROUGH LOOP 137$: .REPT 16. CLR (R1)+ ;CLEAR A WORD OF FAST MAP AREA .ENDR SOB R2,137$ ;LOOP UNTIL DONE 1371$: .ENDC ; DF F$$MAP .IF DF C$$DFB & C$$RTB BIT #T4.DFB,T.ST4(R5) ;TASK HAVE DEFERRED BINDING? BEQ 138$ ;IF EQ NO BIT #F5.RTB,$FMSK5 ;TASK HAVE RUN TIME BINDING? BEQ 138$ ;IF EQ NO MOVB T.HDLN(R5),R1 ;GET LENGTH OF HEADER IN 32. WORD BLOCKS .IF DF F$$MAP BIT #T4.FMP, T.ST4(R5) ; TASK HAVE FAST MAP ENABLED BEQ 1375$ ; IF EQ NO SUB #H$$FMX, R1 ; TAKE FAST MAPPING INTO ACCOUNT 1375$: .ENDC ; DF F$$MAP TST H.LUTE(R0) ;ARE THERE LUNS? BEQ 138$ ;IF EQ NO LUNS SUB H.LUTE(R0), R1 ;SUBTRACT OUT SIZE OF LUT EXTENSION ASH #6, R1 ;GET OFFSET IN BYTES ADD #MAP6, R1 ;GET ADDRESS OF LUT EXTENSION MOV R1,H.LUTE(R0) ;STORE IT IN HEADER ADD #H.NLUN,R0 ;GET ADDRESS OF LUT IN HEADER MOV (R0)+,R2 ;GET NUMBER OF WORDS TO COPY ASL R2 ; MOV R2,-(SP) ;SAVE 1377$: MOV (R0)+,(R1)+ ;COPY THE HEADER LUT INTO THE EXTENSION SOB R2,1377$ ;LOOP UNTIL DONE MOV #MAP6+H.NLUN+2,R1 ;POINT TO HEADER LUT AGAIN MOV (SP)+,R2 ;GET SIZE OF LUT 1378$: CLR (R1)+ ;CLEAR OUT HEADER LUT SOB R2,1378$ ;LOOP UNTIL DONE 138$: MOV #MAP6, R0 ;POINT BACK TO BEGINNING OF HEADER .ENDC ; DF C$$DFB & C$$RTB BR 14000$ ;RE-ENTER CODE .ENDC ; DF X$$HDR 139$: ASR R1 ;CONVERT LENGTH TO WORDS 140$: MOV (R2)+,(R0)+ ;MOVE TASK HEADER TO CORE BLOCK DEC R1 ;ANY MORE WORDS TO MOVE? BGT 140$ ;IF GT YES MOV P.HDR(R4),R0 ;GET ADDRESS OF TASK HEADER 14000$: TSTB IOSB ;SUCCESSFUL READ ? BMI 1421$ ;IF MI NO BIT #PS.CKP,(R3) ;CHECKPOINT READ? BNE 1401$ ;IF NE YES, DON'T TOUCH LUT .IF DF S$$LIB CLR H.SMAP(R0) ;INITIALIZE SUPERVISOR AND DATA MAP MASK .ENDC ; DF S$$LIB CALL REBIND ;BIND LUT AND WINDOWS TO EXEC ADDRESSES 1401$: ;REFERENCE SYMBOL .IF DF M$$PRO MOV H.WND(R0),R1 ;POINT TO NUMBER OF WINDOWS MOV (R1)+,-(SP) ;GET NUMBER OF WINDOWS 141$: TST W.BPCB(R1) ;IS THIS WINDOW MAPPED? BEQ 142$ ;NO IF EQ MOV W.BATT(R1),R2 ;GET ADDRESS OF ATTACHMENT DESCRIPTOR BEQ 142$ ;IF EQ NOT ATTACHED BITB #AS.RBP,A.STAT(R2) ;SHOULD BYPASS BE RESET? BEQ 1411$ ;NO IF EQ BIC #100000,W.BLPD(R1) ;RESET BYPASS IN LPDR BICB #AS.RBP,A.STAT(R2) ;RESET FLAG 1411$: BITB #AS.SBP,A.STAT(R2) ;SHOULD BYPASS BE SET? BEQ 142$ ;NO IF EQ BIS #100000,W.BLPD(R1) ;SET BYPASS IN LPDR BICB #AS.SBP,A.STAT(R2) ;RESET FLAG 142$: ADD #W.BLGH,R1 ;POINT TO NEXT WINDOW DEC (SP) ;ANY WINDOWS LEFT? BGT 141$ ;YES IF GT TST (SP)+ ;CLEAN THE STACK .ENDC 1421$: ;REFERENCE SYMBOL .IF DF S$$WPC MOVB $SWPR,H.SPRI(R0) ;INITIALIZE SWAPPING PRIORITY .ENDC MOV H.WND(R0),R1 ;POINT TO NUMBER OF WINDOW BLOCKS CALL $MAPTK ;MAP FIRST TASK ADDRESS WINDOW CMPB #17,H.IPS(R0) ;VALID TASK IMAGE? BNE 1431$ ;IF NE NO TREAT AS UNSUCCESSFUL READ 143$: TSTB IOSB ;READ ERROR? BPL 1439$ ;IF PL NO ; ; REGION LOAD FAILURE (SYSTEM STATE) ; ; THE FIXED BIT IS CLEARED AND PS.LFR IS SET TO DENOTE THE LOAD FAILURE. ; IF THE REGION IS A TASK REGION, THEN THOSE HEADER FIELDS WHICH ARE ; REQUIRED TO GET THE TASK THROUGH THE ABORT PROCESS ARE FABRICATED ; HERE. (ALL MAPPED TASKS ARE ABORTED LATER.) ; 1431$: BIS #PS.LFR,(R3) ;SIGNIFY LOAD FAILURE BIT #PS.COM,(R3) ;IS IT A COMMON REGION? BNE 1439$ ;IF NE YES MOV #77406,(R1) ;SET ACCESS LAST PDR MOV #UISDR0&377+<1*256.>,-(R1) ;SET FIRST PDR AND # PDR'S MOV H.WND(R0),-(SP) ;GET ADDR OF NUMBER OF WINDOW BLOCKS MOV #1,@(SP)+ ;INDICATE ONE WINDOW BLOCK .IF DF, U$$DAS BIT #T4.DSP,T.ST4(R5) ;TASK BUILT WITH SEPARATE I/D SPACE? BEQ 1435$ ;IF EQ, NO MOV (R1),-20(R1) ;COPY FIRST PDR AND # PDR'S TO WINDOW 0 MOV 2(R1),-16(R1) ;COPY LAST PDR TO WINDOW 0 1435$: ;REFERENCE LABEL .ENDC ; DF U$$DAS CLR H.FPSA(R0) ;CLEAR FLOATING POINT SAVE AREA POINTER MOV R0,H.GARD(R0) ;INITIALIZE GUARD WORD POINTER ADD #H.TKVL+2,H.GARD(R0) ; ; ; POST PROCESSING FOR REGION LOAD (SYSTEM STATE) ; INITIAL TASK LOAD INITIALIZATION ; ; FOR THE INITIAL LOAD OF A TASK REGION, REQUEST OR FIX, THE LOADER MUST ; ATTACH THE TASK TO ANY REGIONS WHICH IT HAS BEEN LINKED TO. THE ; TASK'S ATTACHMENT QUEUE MAY NOT BE EMPTY DUE TO THE SEND BY REFERENCE ; DIRECTIVE. IF THE TASK IS NOT BEING FIXED, $BILDS IS CALLED TO INIT ; ITS STACK AND PLACE THE TASK IN THE ACTIVE TASK LIST. ; 1439$: BIT #PS.COM,(R3) ;COMMON? BNE 150$ ;IF NE, YES .IF DF, U$$DAS CALL CALDMK ;CALCULATE D SPACE MASK .ENDC ; DF U$$DAS BIT #PS.CKP,(R3) ;CHECKPOINT READ? BNE 150$ ;IF NE YES MOV H.WND(R0),R3 ;POINT TO NUMBER OF WINDOW BLOCKS MOV #LDRBK,R1 ;POINT TO SAVE AREA MOV (R3)+,(R1)+ ;SAVE NUMBER OF WINDOW BLOCKS MOV R5,R0 ;COPY TCB POINTER ADD #T.ATT,R0 ;POINT TO ATTACHMENT DESCRIPTOR LISTHEAD MOV R0,-(SP) ;SAVE LISTHEAD POINTER MOV (R0)+,(R1)+ ;SAVE FIRST LISTHEAD WORD .IF DF U$$DAS MOV (R0),(R1)+ ;SAVE SECOND LISTHEAD WORD .IFF ; DF U$$DAS MOV (R0),(R1) ;SAVE SECOND LISTHEAD WORD .IFTF ; DF U$$DAS MOV (SP)+,(R0) ;REINITIALIZE SECOND LISTHEAD WORD .IFT ; DF U$$DAS CLR (R1) ;INIT TEMPORARY TO ZERO (INDICATES ;NOT D-SPACE TASK LATER CLR MUDPT ;CLEAR POINTER TO D WINDOW IN HEADER ;OF MULTI-USER I/D TASK BIT #T4.DSP,T.ST4(R5) ;IS IT D SPACE ? BEQ 145$ ;IF EQ NO MOV R3,(R1) ;SAVE POINTER TO I SPACE WINDOW ADD #W.BLGH,R3 ;POINT TO D SPACE WINDOW DEC -6(R1) ;COUNT AS ONE LESS WINDOW BIT #T4.MUT,T.ST4(R5) ;IS IT A MULTI-USER TASK ? BEQ 145$ ;IF EQ NO MOV #<2*W.BLGH>,MUDPT ;INIT OFFSET FROM D SPACE WINDOW TO ;D SPACE RO WINDOW ADD R3,MUDPT ;FORM REAL ADDRESS OF WINDOW .IFTF ; DF U$$DAS 145$: CLR R1 ;CLR NEXT ATTACHMENT DESCRIPTOR ADDRESS MOV (R3),R2 ;PICK UP NEXT PCB ADDRESS (W.BPCB) BEQ 148$ ;IF EQ THERE IS NONE .IFT ; DF U$$DAS CMP R3,MUDPT ;IS THIS RO D WINDOW IN AN I/D MU TASK ? BNE 1455$ ;IF NE NO MOV W.BATT-W.BLGH(R3),R1 ;GET ADDRESS OF RO I ADB MOV R1,W.BATT(R3) ;SET ADDRESS OF ATTACHMENT ;DESCRIPTOR BR 1481$ ;AND GO SET MAPPING COUNT IN ADB .ENDC ; DF U$$DAS 1455$: MOV #AS.RED,R4 ;SET FOR ATTACH WITH READ ACCESS BIT #4,W.BLPD(R3) ;MAPPED WITH WRITE ACCESS? BEQ 146$ ;IF EQ NO BIS #AS.WRT,R4 ;ADD WRITE ACCESS FOR ATTACH 146$: CALL $CRATT ;ATTACH TO REGION BCC 148$ ;IF CC SUCCESSFUL ; ; NO NEED TO CHANGE FOLLOWING REFERENCE TO $HEADR TO SUPPORT EXTERNAL HEADER ; MOV @$HEADR,R0 ;RETRIEVE SAVED STACK POINTER MOV R3,(R0)+ ;SAVE WINDOW BLOCK POINTER AS R4 MOV R5,(R0)+ ;SAVE TCB ADDRESS AS R5 MOV #147$,(R0) ;MODIFY RETURN ADDRESS CALLR $TKWSE ;WAIT FOR SIGNIFICANT EVENT 147$: CALL $SWSTK,$LOADR ;SWITCH TO SYSTEM STATE MOV R4,R3 ;RESTORE WINDOW BLOCK POINTER BR 145$ ;REATTEMPT THE ATTACH 148$: MOV R1,W.BATT(R3) ;SET ADDRESS OF ATTACHMENT DESCRIPTOR BEQ 1485$ ;IF EQ WINDOW NOT MAPPED MOV T.PCB(R5),R4 ;RESTORE PCB ADDRESS CMP A.PCB(R1),R4 ;IS ATTACHED REGION THE TASK REGION? BEQ 1481$ ;IF EQ YES, DON'T ACCESS IT AGAIN MOV R5,R0 ;COPY TCB ADDRESS MOV R3,-(SP) ;SAVE R3 .IF DF M$$PRO MOV R1,-(SP) ;SAVE R1 MOV A.PCB(R1),R1 ;GET PCB ADDRESS CALL $SETBP ;SET UP CACHE BYPASS AS APPROPRIATE MOV (SP)+,R1 ;RESTORE R1 .ENDC INCB A.MPCT(R1) ;INIT MAPPING COUNT THIS DESCRIPTOR MOV A.PCB(R1),R1 ;POINT TO ATTACHED REGION CALL $ACCRG ;ACCESS COMMON REGION MOV (SP)+,R3 ;RESTORE R3 BR 1485$ ; 1481$: INCB A.MPCT(R1) ;INIT MAPPING COUNT THIS DESCRIPTOR 1485$: ADD #W.BLGH,R3 ;POINT TO NEXT WINDOW BLOCK DEC LDRBK ;ANY MORE WINDOWS TO PROCESS? BGT 145$ ;IF GT YES MOV LDRBK+2,@T.ATT+2(R5) ;ADD ON OLD DESCRIPTORS BEQ 149$ ;IF EQ IT WAS NULL MOV LDRBK+4,T.ATT+2(R5) ;POINT TO LAST ORIGINAL DESCRIPTOR 149$: ;REFERENCE LABEL ; FOR AN I/D TASK, WE SKIPPED THE I SPACE WINDOW IN THE PRECEDING CODE. ; WE WILL NOW FIX UP THE I SPACE WINDOW TO POINT TO THE SAME ATTACHMENT ; DESCRIPTOR AS THE D SPACE WINDOW. SINCE THIS MAPPING IS STATIC, IT DOESN'T ; MATTER THAT THE MAPPING COUNT IN THE ADB WILL BE 1 INSTEAD OF 2, AND THIS ; SIMPLIFIES THE MANAGEMENT OF T.STAT DURING THE TASK REQUEST SEQUENCE. .IF DF U$$DAS MOV LDRBK+6,R0 ;GET POINTER TO TASK I SPACE WINDOW BEQ 1495$ ;IF EQ NOT A D SPACE TASK MOV W.BATT+W.BLGH(R0),W.BATT(R0) ;POINT TASK I SPACE WINDOW ;TO SAME ATTACHEMENT DESCRIPTOR AS TASK ;D SPACE WINDOW .ENDC ; DF U$$DAS 1495$: BIT #PS.FXD,P.STAT(R4) ;REGION BEING FIXED ? BNE 170$ ;IF NE YES MOV R5,R0 ;SET ADDRESS OF TASK TCB CALL $BILDS ;BUILD A STACK FOR TASK JUST STARTING ; ; POST PROCESSING FOR REGION LOAD (SYSTEM STATE) ; FINAL PROCESSING ; ; HERE THE LOADER PERFORMS THE FOLLOWING ACTIONS: ; ; 1. UNBLOCK ALL TASKS MAPPED TO THE REGION. ; 2. FREE UP ANY DYNAMIC CHECKPOINT SPACE FROM WHICH THE REGION MAY ; HAVE BEEN READ. ; 3. IF INSTALLED COMMON IS ONLY TO BE CHECKPOINTED TO SYSTEM ; CHECKPOINT FILE (PS.NWB=1), DEALLOCATE DISK PCB AND ; CONVERT COMMON TO A PLAS REGION. ; 4. CHECK FOR A PENDING CHECKPOINT REQUEST AND INITIATE THE ; CHECKPOINT OPERATION IF THERE IS A REQUEST. ; 5. DECLARE RECEIVE AST'S FOR TASKS'S WITH NONEMPTY ; RECEIVE QUEUES. ; ; INPUTS: ; ; R4=PCB ADDRESS OF REGION. ; R5=TCB ADDRESS (IF TASK REGION). ; ; OUTPUTS: ; ; R4 IS PRESERVED IF COMMON REGION OR LOAD FAILURE. ; R5 IS PRESERVED. ; 150$: CALL 170$ ;SERVICE REGION LOAD ASTS, ;DEALLOCATE CKP SPACE ;AND UNBLOCK TASKS MOV R4,R3 ;RECALCULATE ADDRESS OF PCB STATUS WORD ADD #P.STAT,R3 ; BIT #PS.LFR,(R3) ;LOAD FAILURE THIS REGION? BEQ 155$ ;IF EQ NO BIT #PS.COM,(R3) ;IS IT A COMMON REGION? BEQ 155$ ;IF EQ NO, DO NOT FREE MEMORY BIC #PS.CKR,(R3) ;CLEAR CHECKPOINT REQUEST BIT BIS #PS.OUT,(R3) ;MARK REGION OUT OF MEMORY MOV R4,R1 ;COPY REGION PCB ADDRESS CALLR $RLPR1 ;RELEASE REGION'S MEMORY 155$: BIC #PS.CKP,(R3) ;CLEAR CHECKPOINT BIT BIT #PS.NWB,(R3) ;COMMON CHECKPOINT TO SYSTEM FILE ? BEQ 157$ ;IF EQ, NO. CHECKPOINTS TO TASK FILE BIC #PS.NWB,(R3) ;DON'T NEED THIS ANYMORE MOV P.DPCB-P.STAT(R3),R0 ;GET ADDRESS OF DISK PCB CLR P.DPCB-P.STAT(R3) ;AND ZERO POINTER MOV #P.DLGH,R1 ;GET SIZE OF DISK PCB MOV R3,-(SP) ;SAVE PCB POINTER CALL $DEACB ;DEALLOCATE DISK PCB MOV (SP)+,R3 ;RESTORE COMMON PCB 157$: BIT #PS.CKR,(R3) ;CHECKPOINT REQUESTED ? BEQ 169$ ;IF EQ NO BIC #PS.CKR,(R3) ;CLEAR CHECKPOINT REQUEST FLAG MOV R4,R1 ;SET ADDRESS OF PCB CALLR $ICHKP ;INITIATE CHECKPOINT 169$: RETURN 170$: BIT #PS.AST,P.STAT(R4) ;REGION LOAD AST PENDING ? BEQ 180$ ;IF EQ NO MOV P.STAT(R4),-(SP) ;SAVE CURRENT STATUS OF REGION BIC #^C,(SP) ;CLEAR ALL BUT OUT & CKP BIC (SP),P.STAT(R4) ;CLEAR THOSE FOR REGION MOV R5,-(SP) ;SAVE NON-VOLATILE MOV R4,-(SP) ;REGISTERS MOV P.SWSZ(R4),R0 ;POINT TO FIRST (OR ONLY) AST MOV (R0),P.SWSZ(R4) ;CLOSE UP LIST BNE 175$ ;IF NE STILL MORE LEFT BIC #PS.AST,P.STAT(R4) ;INDICATE NO ASTS LEFT MOV P.SIZE(R4),P.SWSZ(R4) ;RESET SWAP SIZE FROM SIZE 175$: CALL $DSPKA ;DISPATCH KERNEL AST DEC T.STAT(R0) ;UNBLOCK THE TASK FOR THIS REGION BNE 177$ ;IF NE STILL BLOCKED CALL $SETCR ;SET CONDITIONAL SCHEDULE REQUEST 177$: MOV (SP),R1 ;GET REGION PCB ADDRESS CALL $DEARG ;DEACCESS REGION ON TASKS BEHALF MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R5 ; BIS (SP)+,P.STAT(R4) ;RESET OUT/CKP STATUS TO PRIOR BR 170$ ;AND GO AGAIN 180$: CALLR 91$ ;UNBLOCK TASKS ; ; REBIND - BIND INSTALLED TASKS TO EXEC DATABASE AT LOAD TIME ; ; INSERTS CORRECT UCB ADDRESSES INTO LUT FROM DEVICE LIST AND ; PCB ADDRESSES INTO TASK ADDRESS WINDOW BLOCKS FROM TASK PCB VECTOR. ; ; REPLACES LOADR ROUTINE SCHDR FOR TASKS USING DEFERRED BINDING ; (NOTE THAT EXISTING SCHDR FUNCTION MUST BE PRESERVED AND USED FOR ; TASKS WHICH OVERRIDE DEFERRED BINDING) ; ; CREATED 5-FEB-1987 BY L.B. MCCULLEY ; ; INPUTS: ; ; R0 = HEADER ADDRESS ; R5 = TCB ADDRESS ; ; OUTPUTS: ; ; IOSB MAY BE SET TO -1 IF SCHDR IS CALLED AND HEADER IS INVALID ; ; TASK LUT AND WINDOW BLOCKS (W.BPCB OFFSET) CORRECTLY INITIALIZED ; FOR THIS EXEC'S DATABASE. ; ; DESTROYS R1, R2 ; PRESERVES R0, R3, R4, R5 (ALL MEANINGFUL TO CALLER) ; REBIND: SAVNR ; COROUTINE SAVES R4/R5 MOV R3,-(SP) ; SAVE OTHER REGISTERS NEEDED BY CALLER MOV R0,-(SP) .IF DF C$$DFB BIT #F5.DFB,$FMSK5 ; SYSTEM USING DEFERRED BINDING? BEQ 2$ ; NO, GO CHECK HEADER BIT #T4.DFB,T.ST4(R5) ; THIS TASK USING DEFERRED BINDING? BNE 5$ ; YES, GO DO THE BINDING 2$: .ENDC ; DF C$$DFB TST $FMSK4 ; LUT SCAN DISABLED ? BMI 200$ ; YES, SO SKIP IT, JUST RETURN CALL SCHDR ; GO CHECK HEADER ALREADY BOUND OKAY BR 200$ ; RETURN AFTER REGISTER RESTORES .IF DF C$$DFB 5$: .IF DF C$$RTB BIT #F5.RTB, $FMSK5 ; SHOULD LUN BINDING BE FURTHER DEFERED? BNE 100$ ; IF NE, YEP - JUST BIND WINDOWS FOR NOW .ENDC ; DF C$$RTB MOV R0,R3 ; R0 -> HEADER ADD #H.NLUN,R3 ; R3 -> LUT MOV (R3)+,R2 ; R2 = NUMBER OF LUT ENTRIES BEQ 100$ ; NONE, GO DO WINDOWS ; ; GET NEXT LUN AND ASSIGN IT ; 10$: CMP (R3),#"OV ; OVERLAY PSUEDO DEVICE? BNE 12$ ; NO MOV T.LDV(R5),(R3)+ ; YES, GET TASK LOAD DEVICE UCB ADDRESS FROM TCB BR 80$ ; 12$: MOV $DEVHD,R4 ; FIND DEVICE TABLE 15$: CMP D.NAM(R4),(R3) ; FOUND IT YET? BEQ 20$ ; YES, NOW SET UNIT 17$: MOV D.LNK(R4),R4 ; NEXT DEVICE BNE 15$ ; MORE TO GO ; NO MORE DEVICES, CAN'T ASSIGN LUN CLR (R3)+ ; COULDN'T FIND MATCHING DEVICE, DON'T BIND IT BR 80$ 20$: ; ; AT THIS POINT ; R2=REMAINING LUT ENTRIES ; R3->UNIT # IN LUT ; R4->DCB ; CLR R1 ; CREATE AN ACCUMULATOR BISB 2(R3),R1 ; RETRIEVE DESIRED UNIT NUMBER CMPB R1,D.UNIT(R4) ; CHECK FOR UNIT NUMBER IN RANGE OF THIS DCB BLO 17$ ; TOO LOW, TRY OTHER DCBS CMPB R1,D.UNIT+1(R4) BHI 17$ ; TOO HIGH, TRY OTHER DCBS CLR R0 ; CREATE AN ACCUMULATOR BISB D.UNIT(R4),R0 ; EXTRACT FIRST UNIT NUMBER FROM DCB SUB R0,R1 ; GET RELATIVE UNIT NUMBER BEQ 22$ ; OPTIMIZATION FOR FIRST UCB MOV D.UCBL(R4),R0 ; GET UCB LENGTH CALL $MUL ; GET OFFSET TO UCB 22$: ADD D.UCB(R4),R1 ; GET ADDRESS OF DESIRED UCB MOV R1,(R3)+ ; STORE UCB IN TASK LUN 80$: CLR (R3)+ ; CLEAR LUT FILES-11 WINDOW BLOCK POINTER DEC R2 ; ALL UNITS ASSIGNED? BNE 10$ ; NO, DO NEXT ONE ; ; BIND WINDOW BLOCKS ; 100$: MOV (SP),R0 ; RESTORE R0 POINTER TO HEADER MOV H.WND(R0), R1 ; R1 => WINDOW BLOCK STORAGE MOV (R1)+, R2 ; R2 = # WINDOW BLOCKS MOV T.PCB(R5),W.BPCB(R1) ; SET TASK REGION PCB INTO WINDOW 0 DEC R2 ; ONLY TASK REGION? BEQ 200$ ; YEP, MUST BE DONE ADD #W.BLGH,R1 ; POINT TO NEXT WINDOW BLOCK .IFDF U$$DAS ; USER D-SPACE SUPPORT BIT #T4.DSP,T.ST4(R5) ; TASK WITH SEPERATE I/D SPACE? BEQ 110$ ; NOPE MOV T.PCB(R5),W.BPCB(R1) ; SET TASK D-SPACE WINDOW PCB PTR DEC R2 ; LAST REGION? BEQ 200$ ; YEP, DONE ADD #W.BLGH,R1 ; POINT TO NEXT WINDOW BLOCK 110$: .IFTF ;U$$DAS MOV T.PCBV(R5),R4 ; R4 => TASK'S PCB VECTOR BEQ 150$ ; NONE, CAN'T DO IT, GO CLEAR ANY UNUSED WINDOWS MOVB (R4)+,R3 ; LENGTH OF VECTOR TSTB (R4)+ ; SKIP USAGE COUNT .IFT ;U$$DAS BIT #T4.MUT,T.ST4(R5) ; MULTI-USER TASK? BEQ 120$ ; NO, SKIP RO SECTION WINDOW HANDLING MOV (R4)+,W.BPCB(R1) ; SET PCB ADDRESS IN RO SECTION WINDOW ADD #W.BLGH,R1 ; POINT TO NEXT WINDOW BLOCK BIT #T4.DSP,T.ST4(R5) ; USER D-SPACE MULTI-USER TASK? BNE 130$ ; YES, DO D-SPACE RO AND COUNT RO WINDOW BEQ 134$ ; NO, SKIP RO D-SPACE, JUST COUNT RO WINDOW ; .IFF U$$DAS DROPS INTO STATIC MAPPING REBIND LOOP PROPERLY .ENDC ;U$$DAS 120$: BIT #1, (R4)+ ; CLUSTER LIB PCB VECTOR ENTRY? (YES=NO WINDOW) BNE 140$ ; LO BIT SET FLAGS NO WINDOW BLOCK TO INIT 130$: MOV -2(R4),W.BPCB(R1) ; SET PCB ADDRESS IN WINDOW ADD #W.BLGH,R1 ; POINT TO NEXT WINDOW BLOCK 134$: DEC R2 ; COUNT DOWN NUMBER OF WINDOWS BEQ 200$ ; NO MORE WINDOWS IS ALL DONE 140$: DEC R3 ; COUNT DOWN NUMBER OF PCBS IN VECTOR BNE 120$ ; LOOP UNTIL ALL PCBS DONE, THEN... ; ; CLEAR UNUSED WINDOW BLOCKS ; 150$: CLR W.BPCB(R1) ; CLEAR WINDOW PCB ADD #W.BLGH,R1 ; POINT R1 TO NEXT WINDOW BLOCK SOB R2,150$ ; CLEAR ALL UNUSED WINDOWS .ENDC ; DF C$$DFB 200$: MOV (SP)+,R0 MOV (SP)+,R3 ; RESTORE SAVED REGISTERS RETURN ; ; THIS ROUTINE SCANS THE HEADER AND VALIDATES THE LUT AND WINDOW BLOCKS. ; TASKS WHICH ARE SIMULTANEOUSLY INSTALLED IN TWO DIFFERENT SYSTEMS ; MAY HAVE INVALID UCBS IN THE LUT OR INVALID PCBS IN THE WINDOW BLOCKS. ; IF THIS IS THE CASE, THE TASK IS ABORTED. ; ; INPUTS: ; ; R0=HEADER ADDRESS. ; R5=TCB ADDRESS. ; ; OUTPUTS: ; ; IOSB IS SET TO -1 IF THE HEADER IS INVALID. ; ; R0 - R3 ARE DESTROYED. ; SCHDR: TST H.NLUN(R0) ;ANY LUNS? BEQ 100$ ;IF EQ NO BIT #T2.ABO,T.ST2(R5) ;TASK ALREADY MARKED FOR ABORT? BNE 200$ ;IF NE YES MOV #$DEVHD,R2 ;POINT TO DEVICE LISTHEAD 10$: MOV (R2),R2 ;POINT TO NEXT DCB BEQ 60$ ;IF EQ END OF LIST MOVB D.UNIT+1(R2),-(SP) ;CALCULATE NUMBER OF UCBS SUB D.UNIT(R2),(SP) ; INCB (SP) ; MOV D.UCB(R2),R4 ;GET ADDRESS OF FIRST UCB 20$: MOV R0,R1 ;COPY HEADER ADDRESS ADD #H.NLUN,R1 ;POINT TO NUMBER OF LUNS MOV (R1)+,R3 ;GET NUMBER OF LUNS 30$: DEC R3 ;ANY LUNS LEFT? BLT 50$ ;IF LT NO CMP (R1)+,R4 ;UCB MATCH? BNE 40$ ;IF NE NO BIS #1,(R1) ;INDICATE UCB MATCH 40$: TST (R1)+ ;POINT TO NEXT LUT ENTRY BR 30$ ;SCAN NEXT LUT ENTRY 50$: ADD D.UCBL(R2),R4 ;POINT TO NEXT UCB DECB (SP) ;ANY UCBS LEFT? BNE 20$ ;IF NE YES TST (SP)+ ;CLEAN THE STACK BR 10$ ;SCAN NEXT DCB 60$: MOV R0,R1 ;COPY ADDRESS OF HEADER ADD #H.NLUN,R1 ;POINT TO NUMBER OF LUT ENTRIES MOV (R1)+,R3 ;GET NUMBER OF LUT ENTRIES 70$: DEC R3 ;ANY LEFT? BLT 100$ ;IF LT NO TST (R1)+ ;POINT TO SECOND LUT WORD BEQ 80$ ;IF EQ NOT ASSIGNED TST (R1) ;UCB ADDRESS FOUND IN DEVICE TABLES? BNE 80$ ;IF NE YES CLR H.NLUN(R0) ;CLEAR THE NUMBER OF LUNS BR 150$ ;ABORT THE TASK 80$: CLR (R1)+ ;CLEAR SECOND LUT WORD BR 70$ ;SCAN NEXT LUT ENTRY 100$: MOV H.WND(R0),R1 ;POINT TO THE NUMBER OF WINDOWS MOV (R1)+,R3 ;GET NUMBER OF WINDOWS 110$: DEC R3 ;LOOK FOR NEXT WINDOW BLE 200$ ;IF LE NO MORE WINDOWS ADD #W.BLGH,R1 ;POINT TO NEXT WINDOW MOV (R1),R0 ;IS THIS WINDOW MAPPED? BEQ 110$ ;IF EQ NO MOV P.MAIN(R0),R0 ;GET MAIN PCB ADDRESS MOV #$PARHD,R2 ;GET ADDRESS OF PARTITION LIST HEAD 120$: MOV (R2),R2 ;GET ADDRESS OF NEXT PCB BEQ 150$ ;IF EQ END OF LIST CMP R0,R2 ;PCB FOUND IN PARTITION LIST? BNE 120$ ;IF NE NO CONTINUE SEARCH 130$: DEC R3 ;ANY WINDOWS LEFT? BLE 200$ ;IF LE NO ADD #W.BLGH,R1 ;POINT TO NEXT WINDOW BLOCK BR 110$ ;CONTINUE SCANNING 150$: MOV #S.CINS,R0 ;GET ABORT CODE MOV R5,R1 ;COPY TCB ADDRESS MOVB #-1,IOSB ;SET ERROR CODE CALLR $ABTSK ;ABORT THE TASK 200$: RETURN ; ;+ ;**-CALDMK--CALCULATE TASKS DATA SPACE MAP MASK ; ; THIS ROUTINE IS CALLED TO CALCULATE THE I/D OVERMAP MASK FROM THE ; TASKS ADDRESSING WINDOWS. ; ; INPUTS: ; ; R0 = HEADER ADDRESS ; R5 = TCB ADDRESS ; ; OUTPUTS: ; ; R1 = DATA SPACE MAPPING MASK ; ; REGISTERS R0 - R3 ARE DESTROYED. ; ;- .IF DF U$$DAS CALDMK: MOV R3,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; MOV R1,-(SP) ; MOVB H.DMAP(R0),-(SP) ;INITIALIZE D SPACE MAP MASK MOV R0,-(SP) ; BIT #T4.DSP,T.ST4(R5) ;TASK BUILD WITH SEPARATE I/D SPACE ? BEQ 20$ ;IF EQ NO, RETURN WITH ALL OVERMAP MASK MOV H.WND(R0),R0 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R0)+,R2 ;GET NUMBER OF WINDOWS, ADVANCE TO FIRST 10$: DEC R2 ;COUNT ONE LESS WINDOW (REMEMBER THAT WINDOW ;0 CAN NEVER BE A D SPACE WINDOW BLE 20$ ;IF LE DONE ADD #W.BLGH,R0 ;POINT TO NEXT WINDOW ASSUME W.BPCB,0 TST (R0) ;THIS WINDOW MAPPED ? BEQ 10$ ;IF EQ NO MOVB W.BFPD(R0),R3 ;GET PDR ADDRESS BIT #20,R3 ;MAPPED TO D SPACE ? BEQ 10$ ;IF EQ NO SUB #UDSDR0,R3 ;ADJUST TO OFFSET ZERO ASR R3 ;CONVERT TO BYTE INDEX MOVB W.BNPD(R0),R1 ;GET NUMBER OF PDRS ADD R3,R1 ;FORM ENDING PDR NUMBER +1 MOVB $BCMSK-1(R1),R1 ;GET MASK UP TO LAST APR BICB $BCMSK-1(R3),R1 ;GET MASK UP TO FIRST APR BISB R1,2(SP) ;MERGE WITH REST OF MASK BR 10$ ;AND CONTINUE 20$: MOV (SP)+,R0 ;RESTORE HEADER ADDRESS MOVB (SP)+,H.DMAP(R0) ;REWRITE HEADER VALUE MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R2 ; MOV (SP)+,R3 ; RETURN .ENDC ; DF U$$DAS .END $LOADR